Time series prediction using RNNs, with TensorFlow

This notebook illustrates:

  • Creating a Recurrent Neural Network in TensorFlow
  • Creating a Custom Estimator in tf.contrib.learn

This notebook was modified based on the work originally published by VALLIAPPA LAKSHMANAN.

Send any feedback to datalab-feedback@google.com.

Data

We simulate a set of sinusoids with random amplitudes and frequencies.


In [1]:
import numpy as np
import seaborn as sns
import pandas as pd

SEQ_LEN = 40

def create_time_series():
  freq = (np.random.random() * 0.5) + 0.1  # 0.1 to 0.6
  ampl = np.random.random() + 0.5  # 0.5 to 1.5
  x = np.sin(np.arange(0, SEQ_LEN) * freq) * ampl
  return x

for i in xrange(0, 5):
  sns.tsplot( create_time_series() );  # 5 series



In [2]:
# Save the data to disk.

def to_csv(filename, N):
  with open(filename, 'w') as ofp:
    for lineno in xrange(0, N):
      seq = create_time_series()
      line = ",".join(map(str, seq))
      ofp.write(line + '\n')

to_csv('train.csv', 1003)
to_csv('eval.csv',  108)



In [3]:
!head -1 eval.csv


0.0,0.603344721823,1.00706719295,1.07759205352,0.791585493041,0.243675460099,-0.384856880495,-0.886055718533,-1.09409472542,-0.940142247742,-0.475134904281,0.147075271235,0.720624216108,1.05574789145,1.0415674913,0.682774733834,0.0980795624523,-0.519066150545,-0.964473967307,-1.09077654104,-0.856185482572,-0.338317440219,0.291486095099,0.824848726494,1.08530243318,0.986673667505,0.561594680123,-0.0492931657257,-0.643871906132,-1.02541959744,-1.06769761331,-0.756717876328,-0.19537094436,0.430616293925,0.914130099247,1.09519540168,0.913905050504,0.430240655924,-0.19577288827,-0.757013139241

Our CSV file sequences consist of 40 numbers. Each number is one input and the prediction output is the next number given previous numbers as history. With 40 numbers (one instance) input, we will have 40 output numbers. For training, each instance's 0~38 numbers are inputs, and 1~39 are truth. For prediction, it is like "given a series of numbers, predict next n numbers".

Model

We will create a recurrent neural network model based on TensorFlow.

For more info on RNN, see:

We will use TensorFlow's Estimator to build our model. Estimators help construct the training/evaluation/prediction graph. They reuse the common graph, and fork only when needed (i.e. input_fn). They also handle model export. Models exported can be deployed to Google Cloud ML Engine for online prediction.


In [4]:
import tensorflow as tf
import shutil
import tensorflow.contrib.learn as tflearn
import tensorflow.contrib.layers as tflayers
from tensorflow.contrib.learn.python.learn import learn_runner
from tensorflow.contrib.learn.python.learn.utils import saved_model_export_utils
import tensorflow.contrib.rnn as rnn


# tf.decode_csv requires DEFAULTS to infer data types and default values.
DEFAULTS = [[0.0] for x in xrange(0, SEQ_LEN)]

# The Estimator API requires named features.
TIMESERIES_FEATURE_NAME = 'rawdata'

# Training batch size.
BATCH_SIZE = 25


Input

Our CSV file structure is quite simple -- a bunch of floating point numbers (note the type of DEFAULTS). We ask for the data to be read BATCH_SIZE sequences at a time.


In [5]:
def create_input_fn(filename, mode=tf.contrib.learn.ModeKeys.TRAIN):  
  """Creates an input_fn for estimator in training or evaluation."""
  
  def _input_fn():
    """Returns named features and labels, as required by Estimator."""  
    # could be a path to one file or a file pattern.
    input_file_names = tf.train.match_filenames_once(filename)
    
    filename_queue = tf.train.string_input_producer(
        input_file_names, num_epochs=None, shuffle=True)
    reader = tf.TextLineReader()
    _, value = reader.read_up_to(filename_queue, num_records=BATCH_SIZE)

    # parse the csv values
    batch_data = tf.decode_csv(value, record_defaults=DEFAULTS)
    batch_data = tf.transpose(batch_data) # [BATCH_SIZE, SEQ_LEN]

    # Get x and y. They are both of shape [BATCH_SIZE, SEQ_LEN - 1]
    batch_len = tf.shape(batch_data)[0]
    x = tf.slice(batch_data, [0, 0], [batch_len, SEQ_LEN-1])
    y = tf.slice(batch_data, [0, 1], [batch_len, SEQ_LEN-1])
    
    return {TIMESERIES_FEATURE_NAME: x}, y   # dict of features, target

  return _input_fn


Inference Graph

Following Estimator's requirements, we will create a model_fn representing the inference model. Note that this function defines the graph that will be used in training, evaluation and prediction.

To supply a model function to the Estimator API, you need to return a ModelFnOps. The rest of the function creates the necessary objects.


In [6]:
#  We will define one LSTM layer. That's the size of LSTM units.
LSTM_SIZE = 10


def model_fn(features, targets, mode):
  """Define the inference model."""

  uniform_initializer = tf.random_uniform_initializer(minval=-0.08, maxval=0.08)
  input_seq = features[TIMESERIES_FEATURE_NAME]
  
  # RNN requires input tensor rank > 2. Adding one dimension.
  input_seq = tf.expand_dims(input_seq, axis=-1)
  
  # LSTM output will be [BATCH_SIZE, SEQ_LEN - 1, lstm_output_size]
  lstm_cell = rnn.BasicLSTMCell(LSTM_SIZE)
  lstm_outputs, _ = tf.nn.dynamic_rnn(cell=lstm_cell,
                                      inputs=input_seq,
                                      dtype=tf.float32)
  
  # Reshape to [BATCH_SIZE * (SEQ_LEN - 1), lstm_output] so it is 2-D and can
  # be fed to next layer.
  lstm_outputs = tf.reshape(lstm_outputs, [-1, lstm_cell.output_size])
  
  # Add hidden layers on top of LSTM layer to add some "nonlinear" to the model.
  hidden1 = tf.contrib.layers.fully_connected(inputs=lstm_outputs,
                                              num_outputs=100,
                                              activation_fn=None,
                                              weights_initializer=uniform_initializer,
                                              biases_initializer=uniform_initializer)
  
  hidden2 = tf.contrib.layers.fully_connected(inputs=lstm_outputs,
                                              num_outputs=50,
                                              activation_fn=None,
                                              weights_initializer=uniform_initializer,
                                              biases_initializer=uniform_initializer)  
    
  predictions = tf.contrib.layers.fully_connected(inputs=hidden2,
                                                  num_outputs=1,
                                                  activation_fn=None,
                                                  weights_initializer=uniform_initializer,
                                                  biases_initializer=uniform_initializer)
  
  # predictions are all we need when mode is not train/eval. 
  predictions_dict = {"predicted": predictions}

  # If train/evaluation, we'll need to compute loss.
  # If train, we will also need to create an optimizer.
  loss, train_op, eval_metric_ops = None, None, None
  if mode == tf.contrib.learn.ModeKeys.TRAIN or mode == tf.contrib.learn.ModeKeys.EVAL:
    # Note: The reshape below is needed because Estimator needs to know
    # loss shape. Without reshaping below, loss's shape would be unknown.
    targets = tf.reshape(targets, [tf.size(targets)])
    predictions = tf.reshape(predictions, [tf.size(predictions)])
    loss = tf.losses.mean_squared_error(targets, predictions)
    eval_metric_ops = {
      "rmse": tf.metrics.root_mean_squared_error(targets, predictions)
    }

    if mode == tf.contrib.learn.ModeKeys.TRAIN:
      # The learning rate here is unusually high, because we don't add any noise
      # to training/evaluation data and overfitting is not a big problem.
      train_op = tf.contrib.layers.optimize_loss(
          loss=loss,
          global_step=tf.contrib.framework.get_global_step(),
          learning_rate=0.1,
          optimizer="Adagrad")
  
  # return ModelFnOps as Estimator requires.
  return tflearn.ModelFnOps(
      mode=mode,
      predictions=predictions_dict,
      loss=loss,
      train_op=train_op,
      eval_metric_ops=eval_metric_ops)


Training

Distributed training is launched off using an Experiment. The key line here is that we use Estimator rather than, say DNNRegressor. This allows us to provide a model_fn, which will be our RNN defined above. Note also that we specify a serving_input_fn -- this is how we parse the input data provided to us at prediction time using gcloud or Cloud ML Online Prediction.


In [7]:
def get_train():
  return create_input_fn('train.csv', mode=tf.contrib.learn.ModeKeys.TRAIN)


def get_eval():
  return create_input_fn('eval.csv', mode=tf.contrib.learn.ModeKeys.EVAL)


def serving_input_fn():
  feature_placeholders = {
      TIMESERIES_FEATURE_NAME: tf.placeholder(tf.float32, [None, None])
  }
  return tflearn.utils.input_fn_utils.InputFnOps(
      feature_placeholders,
      None,
      feature_placeholders
  )


def experiment_fn(output_dir):
    """An experiment_fn required for Estimator API to run training."""

    estimator = tflearn.Estimator(model_fn=model_fn,
                                  model_dir=output_dir,
                                  config=tf.contrib.learn.RunConfig(save_checkpoints_steps=500))
    return tflearn.Experiment(
        estimator,
        train_input_fn=get_train(),
        eval_input_fn=get_eval(),
        export_strategies=[saved_model_export_utils.make_export_strategy(
            serving_input_fn,
            default_output_alternative_key=None,
            exports_to_keep=1
        )],
        train_steps=1000
    )


shutil.rmtree('training', ignore_errors=True) # start fresh each time.
learn_runner.run(experiment_fn, 'training')


INFO:tensorflow:Using config: {'_save_checkpoints_secs': None, '_num_ps_replicas': 0, '_keep_checkpoint_max': 5, '_task_type': None, '_is_chief': True, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7fe50d43ac10>, '_model_dir': 'training', '_save_checkpoints_steps': 500, '_keep_checkpoint_every_n_hours': 10000, '_session_config': None, '_tf_random_seed': None, '_environment': 'local', '_num_worker_replicas': 0, '_task_id': 0, '_save_summary_steps': 100, '_tf_config': gpu_options {
  per_process_gpu_memory_fraction: 1.0
}
, '_evaluation_master': '', '_master': ''}
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/contrib/learn/python/learn/monitors.py:268: __init__ (from tensorflow.contrib.learn.python.learn.monitors) is deprecated and will be removed after 2016-12-05.
Instructions for updating:
Monitors are deprecated. Please use tf.train.SessionRunHook.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Saving checkpoints for 1 into training/model.ckpt.
INFO:tensorflow:loss = 0.594325, step = 1
INFO:tensorflow:Starting evaluation at 2017-11-21-00:18:43
INFO:tensorflow:Restoring parameters from training/model.ckpt-1
INFO:tensorflow:Evaluation [1/100]
INFO:tensorflow:Evaluation [2/100]
INFO:tensorflow:Evaluation [3/100]
INFO:tensorflow:Evaluation [4/100]
INFO:tensorflow:Evaluation [5/100]
INFO:tensorflow:Evaluation [6/100]
INFO:tensorflow:Evaluation [7/100]
INFO:tensorflow:Evaluation [8/100]
INFO:tensorflow:Evaluation [9/100]
INFO:tensorflow:Evaluation [10/100]
INFO:tensorflow:Evaluation [11/100]
INFO:tensorflow:Evaluation [12/100]
INFO:tensorflow:Evaluation [13/100]
INFO:tensorflow:Evaluation [14/100]
INFO:tensorflow:Evaluation [15/100]
INFO:tensorflow:Evaluation [16/100]
INFO:tensorflow:Evaluation [17/100]
INFO:tensorflow:Evaluation [18/100]
INFO:tensorflow:Evaluation [19/100]
INFO:tensorflow:Evaluation [20/100]
INFO:tensorflow:Evaluation [21/100]
INFO:tensorflow:Evaluation [22/100]
INFO:tensorflow:Evaluation [23/100]
INFO:tensorflow:Evaluation [24/100]
INFO:tensorflow:Evaluation [25/100]
INFO:tensorflow:Evaluation [26/100]
INFO:tensorflow:Evaluation [27/100]
INFO:tensorflow:Evaluation [28/100]
INFO:tensorflow:Evaluation [29/100]
INFO:tensorflow:Evaluation [30/100]
INFO:tensorflow:Evaluation [31/100]
INFO:tensorflow:Evaluation [32/100]
INFO:tensorflow:Evaluation [33/100]
INFO:tensorflow:Evaluation [34/100]
INFO:tensorflow:Evaluation [35/100]
INFO:tensorflow:Evaluation [36/100]
INFO:tensorflow:Evaluation [37/100]
INFO:tensorflow:Evaluation [38/100]
INFO:tensorflow:Evaluation [39/100]
INFO:tensorflow:Evaluation [40/100]
INFO:tensorflow:Evaluation [41/100]
INFO:tensorflow:Evaluation [42/100]
INFO:tensorflow:Evaluation [43/100]
INFO:tensorflow:Evaluation [44/100]
INFO:tensorflow:Evaluation [45/100]
INFO:tensorflow:Evaluation [46/100]
INFO:tensorflow:Evaluation [47/100]
INFO:tensorflow:Evaluation [48/100]
INFO:tensorflow:Evaluation [49/100]
INFO:tensorflow:Evaluation [50/100]
INFO:tensorflow:Evaluation [51/100]
INFO:tensorflow:Evaluation [52/100]
INFO:tensorflow:Evaluation [53/100]
INFO:tensorflow:Evaluation [54/100]
INFO:tensorflow:Evaluation [55/100]
INFO:tensorflow:Evaluation [56/100]
INFO:tensorflow:Evaluation [57/100]
INFO:tensorflow:Evaluation [58/100]
INFO:tensorflow:Evaluation [59/100]
INFO:tensorflow:Evaluation [60/100]
INFO:tensorflow:Evaluation [61/100]
INFO:tensorflow:Evaluation [62/100]
INFO:tensorflow:Evaluation [63/100]
INFO:tensorflow:Evaluation [64/100]
INFO:tensorflow:Evaluation [65/100]
INFO:tensorflow:Evaluation [66/100]
INFO:tensorflow:Evaluation [67/100]
INFO:tensorflow:Evaluation [68/100]
INFO:tensorflow:Evaluation [69/100]
INFO:tensorflow:Evaluation [70/100]
INFO:tensorflow:Evaluation [71/100]
INFO:tensorflow:Evaluation [72/100]
INFO:tensorflow:Evaluation [73/100]
INFO:tensorflow:Evaluation [74/100]
INFO:tensorflow:Evaluation [75/100]
INFO:tensorflow:Evaluation [76/100]
INFO:tensorflow:Evaluation [77/100]
INFO:tensorflow:Evaluation [78/100]
INFO:tensorflow:Evaluation [79/100]
INFO:tensorflow:Evaluation [80/100]
INFO:tensorflow:Evaluation [81/100]
INFO:tensorflow:Evaluation [82/100]
INFO:tensorflow:Evaluation [83/100]
INFO:tensorflow:Evaluation [84/100]
INFO:tensorflow:Evaluation [85/100]
INFO:tensorflow:Evaluation [86/100]
INFO:tensorflow:Evaluation [87/100]
INFO:tensorflow:Evaluation [88/100]
INFO:tensorflow:Evaluation [89/100]
INFO:tensorflow:Evaluation [90/100]
INFO:tensorflow:Evaluation [91/100]
INFO:tensorflow:Evaluation [92/100]
INFO:tensorflow:Evaluation [93/100]
INFO:tensorflow:Evaluation [94/100]
INFO:tensorflow:Evaluation [95/100]
INFO:tensorflow:Evaluation [96/100]
INFO:tensorflow:Evaluation [97/100]
INFO:tensorflow:Evaluation [98/100]
INFO:tensorflow:Evaluation [99/100]
INFO:tensorflow:Evaluation [100/100]
INFO:tensorflow:Finished evaluation at 2017-11-21-00:18:44
INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 0.57911, rmse = 0.743714
INFO:tensorflow:Validation (step 1): loss = 0.57911, global_step = 1, rmse = 0.743714
INFO:tensorflow:global_step/sec: 17.1556
INFO:tensorflow:loss = 0.0498386, step = 101 (5.830 sec)
INFO:tensorflow:global_step/sec: 28.6204
INFO:tensorflow:loss = 0.0213993, step = 201 (3.495 sec)
INFO:tensorflow:global_step/sec: 30.2789
INFO:tensorflow:loss = 0.0105503, step = 301 (3.301 sec)
INFO:tensorflow:global_step/sec: 29.8901
INFO:tensorflow:loss = 0.00411154, step = 401 (3.346 sec)
INFO:tensorflow:Saving checkpoints for 501 into training/model.ckpt.
INFO:tensorflow:global_step/sec: 26.5689
INFO:tensorflow:loss = 0.00593007, step = 501 (3.764 sec)
INFO:tensorflow:Starting evaluation at 2017-11-21-00:19:02
INFO:tensorflow:Restoring parameters from training/model.ckpt-501
INFO:tensorflow:Evaluation [1/100]
INFO:tensorflow:Evaluation [2/100]
INFO:tensorflow:Evaluation [3/100]
INFO:tensorflow:Evaluation [4/100]
INFO:tensorflow:Evaluation [5/100]
INFO:tensorflow:Evaluation [6/100]
INFO:tensorflow:Evaluation [7/100]
INFO:tensorflow:Evaluation [8/100]
INFO:tensorflow:Evaluation [9/100]
INFO:tensorflow:Evaluation [10/100]
INFO:tensorflow:Evaluation [11/100]
INFO:tensorflow:Evaluation [12/100]
INFO:tensorflow:Evaluation [13/100]
INFO:tensorflow:Evaluation [14/100]
INFO:tensorflow:Evaluation [15/100]
INFO:tensorflow:Evaluation [16/100]
INFO:tensorflow:Evaluation [17/100]
INFO:tensorflow:Evaluation [18/100]
INFO:tensorflow:Evaluation [19/100]
INFO:tensorflow:Evaluation [20/100]
INFO:tensorflow:Evaluation [21/100]
INFO:tensorflow:Evaluation [22/100]
INFO:tensorflow:Evaluation [23/100]
INFO:tensorflow:Evaluation [24/100]
INFO:tensorflow:Evaluation [25/100]
INFO:tensorflow:Evaluation [26/100]
INFO:tensorflow:Evaluation [27/100]
INFO:tensorflow:Evaluation [28/100]
INFO:tensorflow:Evaluation [29/100]
INFO:tensorflow:Evaluation [30/100]
INFO:tensorflow:Evaluation [31/100]
INFO:tensorflow:Evaluation [32/100]
INFO:tensorflow:Evaluation [33/100]
INFO:tensorflow:Evaluation [34/100]
INFO:tensorflow:Evaluation [35/100]
INFO:tensorflow:Evaluation [36/100]
INFO:tensorflow:Evaluation [37/100]
INFO:tensorflow:Evaluation [38/100]
INFO:tensorflow:Evaluation [39/100]
INFO:tensorflow:Evaluation [40/100]
INFO:tensorflow:Evaluation [41/100]
INFO:tensorflow:Evaluation [42/100]
INFO:tensorflow:Evaluation [43/100]
INFO:tensorflow:Evaluation [44/100]
INFO:tensorflow:Evaluation [45/100]
INFO:tensorflow:Evaluation [46/100]
INFO:tensorflow:Evaluation [47/100]
INFO:tensorflow:Evaluation [48/100]
INFO:tensorflow:Evaluation [49/100]
INFO:tensorflow:Evaluation [50/100]
INFO:tensorflow:Evaluation [51/100]
INFO:tensorflow:Evaluation [52/100]
INFO:tensorflow:Evaluation [53/100]
INFO:tensorflow:Evaluation [54/100]
INFO:tensorflow:Evaluation [55/100]
INFO:tensorflow:Evaluation [56/100]
INFO:tensorflow:Evaluation [57/100]
INFO:tensorflow:Evaluation [58/100]
INFO:tensorflow:Evaluation [59/100]
INFO:tensorflow:Evaluation [60/100]
INFO:tensorflow:Evaluation [61/100]
INFO:tensorflow:Evaluation [62/100]
INFO:tensorflow:Evaluation [63/100]
INFO:tensorflow:Evaluation [64/100]
INFO:tensorflow:Evaluation [65/100]
INFO:tensorflow:Evaluation [66/100]
INFO:tensorflow:Evaluation [67/100]
INFO:tensorflow:Evaluation [68/100]
INFO:tensorflow:Evaluation [69/100]
INFO:tensorflow:Evaluation [70/100]
INFO:tensorflow:Evaluation [71/100]
INFO:tensorflow:Evaluation [72/100]
INFO:tensorflow:Evaluation [73/100]
INFO:tensorflow:Evaluation [74/100]
INFO:tensorflow:Evaluation [75/100]
INFO:tensorflow:Evaluation [76/100]
INFO:tensorflow:Evaluation [77/100]
INFO:tensorflow:Evaluation [78/100]
INFO:tensorflow:Evaluation [79/100]
INFO:tensorflow:Evaluation [80/100]
INFO:tensorflow:Evaluation [81/100]
INFO:tensorflow:Evaluation [82/100]
INFO:tensorflow:Evaluation [83/100]
INFO:tensorflow:Evaluation [84/100]
INFO:tensorflow:Evaluation [85/100]
INFO:tensorflow:Evaluation [86/100]
INFO:tensorflow:Evaluation [87/100]
INFO:tensorflow:Evaluation [88/100]
INFO:tensorflow:Evaluation [89/100]
INFO:tensorflow:Evaluation [90/100]
INFO:tensorflow:Evaluation [91/100]
INFO:tensorflow:Evaluation [92/100]
INFO:tensorflow:Evaluation [93/100]
INFO:tensorflow:Evaluation [94/100]
INFO:tensorflow:Evaluation [95/100]
INFO:tensorflow:Evaluation [96/100]
INFO:tensorflow:Evaluation [97/100]
INFO:tensorflow:Evaluation [98/100]
INFO:tensorflow:Evaluation [99/100]
INFO:tensorflow:Evaluation [100/100]
INFO:tensorflow:Finished evaluation at 2017-11-21-00:19:04
INFO:tensorflow:Saving dict for global step 501: global_step = 501, loss = 0.00698184, rmse = 0.0829543
INFO:tensorflow:Validation (step 501): loss = 0.00698184, global_step = 501, rmse = 0.0829543
INFO:tensorflow:global_step/sec: 19.5328
INFO:tensorflow:loss = 0.00520417, step = 601 (5.119 sec)
INFO:tensorflow:global_step/sec: 26.9615
INFO:tensorflow:loss = 0.00252773, step = 701 (3.710 sec)
INFO:tensorflow:global_step/sec: 29.472
INFO:tensorflow:loss = 0.00375434, step = 801 (3.397 sec)
INFO:tensorflow:global_step/sec: 28.1198
INFO:tensorflow:loss = 0.00460393, step = 901 (3.552 sec)
INFO:tensorflow:Saving checkpoints for 1000 into training/model.ckpt.
INFO:tensorflow:Loss for final step: 0.0024113.
INFO:tensorflow:Starting evaluation at 2017-11-21-00:19:22
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Evaluation [1/100]
INFO:tensorflow:Evaluation [2/100]
INFO:tensorflow:Evaluation [3/100]
INFO:tensorflow:Evaluation [4/100]
INFO:tensorflow:Evaluation [5/100]
INFO:tensorflow:Evaluation [6/100]
INFO:tensorflow:Evaluation [7/100]
INFO:tensorflow:Evaluation [8/100]
INFO:tensorflow:Evaluation [9/100]
INFO:tensorflow:Evaluation [10/100]
INFO:tensorflow:Evaluation [11/100]
INFO:tensorflow:Evaluation [12/100]
INFO:tensorflow:Evaluation [13/100]
INFO:tensorflow:Evaluation [14/100]
INFO:tensorflow:Evaluation [15/100]
INFO:tensorflow:Evaluation [16/100]
INFO:tensorflow:Evaluation [17/100]
INFO:tensorflow:Evaluation [18/100]
INFO:tensorflow:Evaluation [19/100]
INFO:tensorflow:Evaluation [20/100]
INFO:tensorflow:Evaluation [21/100]
INFO:tensorflow:Evaluation [22/100]
INFO:tensorflow:Evaluation [23/100]
INFO:tensorflow:Evaluation [24/100]
INFO:tensorflow:Evaluation [25/100]
INFO:tensorflow:Evaluation [26/100]
INFO:tensorflow:Evaluation [27/100]
INFO:tensorflow:Evaluation [28/100]
INFO:tensorflow:Evaluation [29/100]
INFO:tensorflow:Evaluation [30/100]
INFO:tensorflow:Evaluation [31/100]
INFO:tensorflow:Evaluation [32/100]
INFO:tensorflow:Evaluation [33/100]
INFO:tensorflow:Evaluation [34/100]
INFO:tensorflow:Evaluation [35/100]
INFO:tensorflow:Evaluation [36/100]
INFO:tensorflow:Evaluation [37/100]
INFO:tensorflow:Evaluation [38/100]
INFO:tensorflow:Evaluation [39/100]
INFO:tensorflow:Evaluation [40/100]
INFO:tensorflow:Evaluation [41/100]
INFO:tensorflow:Evaluation [42/100]
INFO:tensorflow:Evaluation [43/100]
INFO:tensorflow:Evaluation [44/100]
INFO:tensorflow:Evaluation [45/100]
INFO:tensorflow:Evaluation [46/100]
INFO:tensorflow:Evaluation [47/100]
INFO:tensorflow:Evaluation [48/100]
INFO:tensorflow:Evaluation [49/100]
INFO:tensorflow:Evaluation [50/100]
INFO:tensorflow:Evaluation [51/100]
INFO:tensorflow:Evaluation [52/100]
INFO:tensorflow:Evaluation [53/100]
INFO:tensorflow:Evaluation [54/100]
INFO:tensorflow:Evaluation [55/100]
INFO:tensorflow:Evaluation [56/100]
INFO:tensorflow:Evaluation [57/100]
INFO:tensorflow:Evaluation [58/100]
INFO:tensorflow:Evaluation [59/100]
INFO:tensorflow:Evaluation [60/100]
INFO:tensorflow:Evaluation [61/100]
INFO:tensorflow:Evaluation [62/100]
INFO:tensorflow:Evaluation [63/100]
INFO:tensorflow:Evaluation [64/100]
INFO:tensorflow:Evaluation [65/100]
INFO:tensorflow:Evaluation [66/100]
INFO:tensorflow:Evaluation [67/100]
INFO:tensorflow:Evaluation [68/100]
INFO:tensorflow:Evaluation [69/100]
INFO:tensorflow:Evaluation [70/100]
INFO:tensorflow:Evaluation [71/100]
INFO:tensorflow:Evaluation [72/100]
INFO:tensorflow:Evaluation [73/100]
INFO:tensorflow:Evaluation [74/100]
INFO:tensorflow:Evaluation [75/100]
INFO:tensorflow:Evaluation [76/100]
INFO:tensorflow:Evaluation [77/100]
INFO:tensorflow:Evaluation [78/100]
INFO:tensorflow:Evaluation [79/100]
INFO:tensorflow:Evaluation [80/100]
INFO:tensorflow:Evaluation [81/100]
INFO:tensorflow:Evaluation [82/100]
INFO:tensorflow:Evaluation [83/100]
INFO:tensorflow:Evaluation [84/100]
INFO:tensorflow:Evaluation [85/100]
INFO:tensorflow:Evaluation [86/100]
INFO:tensorflow:Evaluation [87/100]
INFO:tensorflow:Evaluation [88/100]
INFO:tensorflow:Evaluation [89/100]
INFO:tensorflow:Evaluation [90/100]
INFO:tensorflow:Evaluation [91/100]
INFO:tensorflow:Evaluation [92/100]
INFO:tensorflow:Evaluation [93/100]
INFO:tensorflow:Evaluation [94/100]
INFO:tensorflow:Evaluation [95/100]
INFO:tensorflow:Evaluation [96/100]
INFO:tensorflow:Evaluation [97/100]
INFO:tensorflow:Evaluation [98/100]
INFO:tensorflow:Evaluation [99/100]
INFO:tensorflow:Evaluation [100/100]
INFO:tensorflow:Finished evaluation at 2017-11-21-00:19:23
INFO:tensorflow:Saving dict for global step 1000: global_step = 1000, loss = 0.00316858, rmse = 0.0563145
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:No assets to write.
INFO:tensorflow:SavedModel written to: training/export/Servo/1511223564/saved_model.pb
Out[7]:
({'global_step': 1000, 'loss': 0.0031685797, 'rmse': 0.056314532},
 ['training/export/Servo/1511223564'])

Model Summary

We can plot model's training summary events using Datalab's ML library.


In [8]:
from google.datalab.ml import Summary

summary = Summary('./training')
summary.plot(['OptimizeLoss/loss', 'loss'])


Prediction

We will generate another instance for prediction which is independent on training or evaluation data.


In [9]:
prediction_data = create_time_series()

# First 30 values as x, Last 10 values as y.
prediction_x = list(prediction_data[:30])
prediction_y = list(prediction_data[30:])

print('x\n%s\n' % prediction_x)
print('y\n%s' % prediction_y)

sns.tsplot(prediction_x, color='blue')
y_truth_curve = [np.nan] * (len(prediction_x)-1) + [prediction_x[-1]] + prediction_y
sns.tsplot(y_truth_curve, color='green')


x
[0.0, 0.22900249487279495, 0.4439029978008785, 0.63146791863105312, 0.78014699454139269, 0.88078455614934603, 0.92718333436437694, 0.91648608871407833, 0.84935155644091942, 0.72991388741018415, 0.56552806283071111, 0.36631697492396786, 0.14454805841165241, -0.086122139095339542, -0.31148892839073794, -0.51767420456998936, -0.69198106183993568, -0.82367566999277042, -0.90464826452848279, -0.9299125466012057, -0.89791273970083441, -0.81061939449491505, -0.6734080421609776, -0.49472816874680836, -0.2855828951440319, -0.058851404023819359, 0.17150416126178541, 0.39129848658386213, 0.58699661981489393, 0.74654745426299995]

y
[0.8601258367855944, 0.92073760150550399, 0.92465027110491749, 0.8716229030770557, 0.76492092698500547, 0.61111505904812813, 0.41967667691189403, 0.20239457145516851, -0.027351007894710573, -0.25541230999151782]
Out[9]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe4e8277cd0>

First prediction we will do is just sending x, and for each value in x it will return a predicted value. And then we can compare the predicted values with the truth (x+1).


In [10]:
# Load model.
estimator = tflearn.Estimator(model_fn=model_fn, model_dir='training')

# Feed Prediction data.
predict_input_fn = lambda: {TIMESERIES_FEATURE_NAME: [prediction_x]}

predicted = list(estimator.predict(input_fn=predict_input_fn))
predicted = [p['predicted'] for p in predicted]

# Plot prediction source.
sns.tsplot(prediction_x, color='green')

# Plot predicted values.
sns.tsplot([prediction_x[0]] + predicted, color='red');


INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_save_checkpoints_secs': 600, '_num_ps_replicas': 0, '_keep_checkpoint_max': 5, '_task_type': None, '_is_chief': True, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7fe4e8127090>, '_model_dir': 'training', '_save_checkpoints_steps': None, '_keep_checkpoint_every_n_hours': 10000, '_session_config': None, '_tf_random_seed': None, '_environment': 'local', '_num_worker_replicas': 0, '_task_id': 0, '_save_summary_steps': 100, '_tf_config': gpu_options {
  per_process_gpu_memory_fraction: 1.0
}
, '_evaluation_master': '', '_master': ''}
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000

The next prediction is sending x, and predict next n values. We make n predictions and take only the last predicted value each time, append it to x for next prediction source.


In [11]:
estimator = tflearn.Estimator(model_fn=model_fn, model_dir='training')

# Prediction data starts with x.
x_total = list(prediction_x)

# Make n predictions.
for i in range(len(prediction_y)):
  predict_input_fn = lambda: {TIMESERIES_FEATURE_NAME: [x_total]}
  p = list(estimator.predict(input_fn=predict_input_fn))
  # For each step, append the tail element of last predicted values.  
  x_total.append(p[-1]['predicted'])

# The first len(prediction_x) elements are prediction source. So remove them.
y_predicted = x_total[len(prediction_x):]

# Zero out prediction source (making them nan), add the last value of prediction source
# so the first edge in the curve is plotted, and add predicted values.
y_predicted_curve = [np.nan] * (len(prediction_x)-1) + [prediction_x[-1]] + y_predicted

# Plot prediction source.
sns.tsplot(prediction_x, color='blue')

# Plot truth curve.
sns.tsplot(y_truth_curve, color='green')

# Plot predicted curve.
sns.tsplot(y_predicted_curve, color='red');


INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_save_checkpoints_secs': 600, '_num_ps_replicas': 0, '_keep_checkpoint_max': 5, '_task_type': None, '_is_chief': True, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7fe4e82adb10>, '_model_dir': 'training', '_save_checkpoints_steps': None, '_keep_checkpoint_every_n_hours': 10000, '_session_config': None, '_tf_random_seed': None, '_environment': 'local', '_num_worker_replicas': 0, '_task_id': 0, '_save_summary_steps': 100, '_tf_config': gpu_options {
  per_process_gpu_memory_fraction: 1.0
}
, '_evaluation_master': '', '_master': ''}
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000
INFO:tensorflow:Restoring parameters from training/model.ckpt-1000

In [ ]: